package vashion.azeroth.core.manager.forest;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.google.common.collect.Lists;

import vashion.azeroth.contant.AzerothConstants;
import vashion.azeroth.contant.ForestErrorEnum;
import vashion.azeroth.core.common.NeedOperateFlow;
import vashion.azeroth.core.dao.BaseDao;
import vashion.azeroth.core.item.dao.ForestPropertyDao;
import vashion.azeroth.core.item.pojo.ForestDO;
import vashion.azeroth.core.item.pojo.ForestPropertyDO;
import vashion.azeroth.core.item.pojo.ForestPropertyValueDO;
import vashion.azeroth.core.item.pojo.PropertyMetaDO;
import vashion.azeroth.core.item.pojo.PropertyValueDO;
import vashion.azeroth.core.manager.impl.BaseManagerImpl;
import vashion.azeroth.core.pojo.common.OperateFlowEnum;
import vashion.azeroth.core.result.ApiResult;

/**
 * Created by tingting on 15/9/1. 基础的类目属性管理
 */
@Service
public class BaseForestPropertyManager extends BaseManagerImpl<ForestPropertyDO> {

	private final static Logger log = LoggerFactory.getLogger(BaseForestPropertyManager.class);

	@Autowired
	private ForestPropertyDao forestPropertyDao;

	@Autowired
	private BasePropertyValueManager basePropertyValueManager;

	@Autowired
	private BaseForestManager baseForestManager;

	@Autowired
	BasePropertyManager basePropertyManager;

	@Override
	public BaseDao<ForestPropertyDO> getDao() {
		return forestPropertyDao;
	}

	@NeedOperateFlow(operateIdArgLocation = 2, operateFlowEnum = OperateFlowEnum.FOREST)
	public ApiResult<Boolean> publishForestProperty(ForestPropertyDO forestPropertyDO, long operateId) {
		if (null == forestPropertyDO || forestPropertyDO.getPropertyId() <= 0 || forestPropertyDO.getForestId() <= 0) {
			return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_ARG_ERROR.getErrorCode(),
					ForestErrorEnum.FOREST_PROPERTY_ARG_ERROR.getErrorMessage());
		}
		forestPropertyDO.setGmtCreate(new Date());
		forestPropertyDO.setGmtModified(new Date());
		try {
			this.save(forestPropertyDO);
		} catch (Exception e) {
			log.error("BaseForestPropertyManager.publishProperty error, forestPropertyDO=" + forestPropertyDO, e);
			return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorCode(),
					ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorMessage());
		}
		return ApiResult.newSuccessResult(true);
	}

	@NeedOperateFlow(operateIdArgLocation = 2, operateFlowEnum = OperateFlowEnum.FOREST)
	public ApiResult<Boolean> publishPropertiesToForest(ForestPropertyDO forestPropertyDO, String propertyValues,
			long operateId) {
		if (null == forestPropertyDO || null == forestPropertyDO.getPropertyTitle()
				|| forestPropertyDO.getForestId() <= 0) {
			return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_ARG_ERROR.getErrorCode(),
					ForestErrorEnum.FOREST_PROPERTY_ARG_ERROR.getErrorMessage());
		}

		try {
			// 查询出forest
			ForestDO forestDO = baseForestManager.get(forestPropertyDO.getForestId());
			if (null == forestDO) {
				return ApiResult.newErrorResult(ForestErrorEnum.IS_NULL.getErrorCode(),
						ForestErrorEnum.IS_NULL.getErrorMessage());
			}

			// 保存新的propertyMeta
			PropertyMetaDO propertyMeta = new PropertyMetaDO();
			propertyMeta.setTitle(forestPropertyDO.getPropertyTitle());
			propertyMeta.setStatus(forestPropertyDO.getStatus());
			propertyMeta = basePropertyManager.save(propertyMeta);
			long propertyMetaId = propertyMeta.getId();
			
			// 保存propertyValues
			if (StringUtils.isNotEmpty(propertyValues)) {
				String[] propertyValueArr = propertyValues.split(",");
				for (String propertyValueStr : propertyValueArr) {
					PropertyValueDO propertyValue = new PropertyValueDO();
					propertyValue.setGmtCreate(new Date());
					propertyValue.setGmtModified(new Date());
					propertyValue.setPropertyMetaId(propertyMetaId);
					propertyValue.setPropertyMetaTitle(propertyMeta.getTitle());
					propertyValue.setValue(propertyValueStr);
					propertyValue.setStatus(AzerothConstants.ItemForestProperty.NORMAL);
					basePropertyValueManager.save(propertyValue);
				}
			}
			
			// 关联forest和propertyMeta
			forestPropertyDO.setGmtCreate(new Date());
			forestPropertyDO.setGmtModified(new Date());
			forestPropertyDO.setPropertyId(propertyMetaId);
			forestPropertyDO.setStatus(AzerothConstants.ItemForestProperty.NORMAL);
			this.save(forestPropertyDO);
		} catch (Exception e) {
			log.error("BaseForestPropertyManager.publishProperty error, forestPropertyDO=" + forestPropertyDO, e);
			return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorCode(),
					ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorMessage());
		}
		return ApiResult.newSuccessResult(true);
	}

	public ApiResult<List<ForestPropertyDO>> getForestPropertyList(long forestId, Integer status) {

		try {
			ForestPropertyDO forestPropertyDO = new ForestPropertyDO();
			forestPropertyDO.setForestId(forestId);
			forestPropertyDO.setStatus(status);
			forestPropertyDO.setPageSize(AzerothConstants.ItemConstant.max_forest_property_count);
			return ApiResult.newSuccessResult(forestPropertyDao.find(forestPropertyDO));
		} catch (Exception e) {
			log.error(" forestPropertyDao.getForestPropertyList error, forestId=" + forestId, e);
			return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorCode(),
					ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorMessage());
		}
	}

	@NeedOperateFlow(operateIdArgLocation = 2, operateFlowEnum = OperateFlowEnum.FOREST)
	public int operateRemove(ForestPropertyDO forestPropertyDO, Long loginUserId) {
		return this.remove(forestPropertyDO);
	}

	// 根据类目ID获得属性的数据
	public ApiResult<ForestPropertyValueDO> getForestPropertyValues(long forestId, Integer status) {
		List<ForestPropertyDO> forestPropertyList = getForestPropertyList(forestId, status).getData();
		ForestPropertyValueDO forestPropertyValueDO = new ForestPropertyValueDO();
		if (null != forestPropertyList && !forestPropertyList.isEmpty()
				&& AzerothConstants.ItemForestProperty.DELETE != forestPropertyList.get(0).getStatus()) {
			ForestPropertyDO forestPropertyDO = forestPropertyList.get(0);
			forestPropertyValueDO.setForestId(forestId);
			forestPropertyValueDO.setPropertyMetaId(forestPropertyDO.getPropertyId());
			forestPropertyValueDO.setPropertyMetaTitle(forestPropertyDO.getPropertyTitle());
			forestPropertyValueDO.setPropertyType(forestPropertyDO.getPropertyType());
			forestPropertyValueDO.setStatus(forestPropertyDO.getStatus());
			ApiResult<List<PropertyValueDO>> propertyValuesResult = basePropertyValueManager.getFromMetaId(forestPropertyDO.getPropertyId(), 1, 1000);
			if (null != propertyValuesResult) {
				forestPropertyValueDO.setPropertyValueDOList(propertyValuesResult.getData());
			}
		} else {
			log.error(" forestPropertyDao.getForestPropertyValue error, forestId=" + forestId);
			return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_IS_NULL.getErrorCode(),
					ForestErrorEnum.FOREST_PROPERTY_IS_NULL.getErrorMessage());
		}
		return ApiResult.newSuccessResult(forestPropertyValueDO);

	}
	
	public ApiResult<List<ForestPropertyValueDO>> getPropertiesForForest(ForestPropertyDO forestProperty, String propertyValue)  {
		if (null == forestProperty || forestProperty.getForestId() <= 0) {
			return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_ARG_ERROR.getErrorCode(),
					ForestErrorEnum.FOREST_PROPERTY_ARG_ERROR.getErrorMessage());
		}

		List<ForestPropertyValueDO> propertyValues = Lists.<ForestPropertyValueDO>newArrayList();
		try {
			// 查询出forest
			ForestDO forestDO = baseForestManager.get(forestProperty.getForestId());
			if (null == forestDO) {
				return ApiResult.newErrorResult(ForestErrorEnum.IS_NULL.getErrorCode(),
						ForestErrorEnum.IS_NULL.getErrorMessage());
			}

			// 查询propertyMeta
			ApiResult<List<ForestPropertyDO>> propertyMetasResult = this.getForestPropertyList(forestProperty.getForestId(), forestProperty.getStatus());
			if (propertyMetasResult.isSuccess() && !CollectionUtils.isEmpty(propertyMetasResult.getData())) {
				List<ForestPropertyDO> propertyMetas = propertyMetasResult.getData();
				for (ForestPropertyDO propertyMeta : propertyMetas) {
					//设置进ForestPropertyValue
					if (forestProperty.getPropertyId() > 0 && forestProperty.getPropertyId()  != propertyMeta.getPropertyId()) {
						continue;
					}
					ForestPropertyValueDO forestPropertyValue = new ForestPropertyValueDO();
					forestPropertyValue.setForestId(propertyMeta.getForestId());
					forestPropertyValue.setPropertyMetaId(propertyMeta.getPropertyId());
					forestPropertyValue.setPropertyMetaTitle(propertyMeta.getPropertyTitle());
					forestPropertyValue.setPropertyType(propertyMeta.getPropertyType());
					forestPropertyValue.setStatus(propertyMeta.getStatus());
					//查询property values
					PropertyValueDO propertyValueQuery = new PropertyValueDO();
					propertyValueQuery.setPropertyMetaId(propertyMeta.getPropertyId());
					propertyValueQuery.setValue(propertyValue);
					List<PropertyValueDO> propertyValueList = basePropertyValueManager.find(propertyValueQuery);
					
					forestPropertyValue.setPropertyValueDOList(propertyValueList);
					
					propertyValues.add(forestPropertyValue);
				}
			}
			
		} catch (Exception e) {
			log.error("BaseForestPropertyManager.publishProperty error, forestPropertyDO=" + forestProperty, e);
			return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorCode(),
					ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorMessage());
		}
		return ApiResult.newSuccessResult(propertyValues);
	}
	
	/**
	 * 根据property value值和类目查询propertyValue
	 * 
	 * @param forestId
	 * @param value
	 * @param status
	 * @return propertyValue
	 */
	public PropertyValueDO getPropertyValueByForestAndValue(long forestId, String value, Integer status) {
		List<ForestPropertyDO> forestPropertyList = getForestPropertyList(forestId, status).getData();
		PropertyValueDO propertyValueDO = new PropertyValueDO();
		if (!CollectionUtils.hasUniqueObject(forestPropertyList)
				&& AzerothConstants.ItemForestProperty.DELETE != forestPropertyList.get(0).getStatus()) {
			ForestPropertyDO forestPropertyDO = forestPropertyList.get(0);
			propertyValueDO.setValue(value);
			propertyValueDO.setPropertyMetaId(forestPropertyDO.getPropertyId());
			propertyValueDO.setStatus(forestPropertyDO.getStatus());
			propertyValueDO = basePropertyValueManager.findByValue(propertyValueDO);
		} else {
			log.error(" forestPropertyDao.getForestPropertyValue error, forestId=" + forestId);
			return null;
		}
		return propertyValueDO;
	}
}
